VM Importでイメージインポートしてみた
こんにちわ。A.T.フィールドよりIフィールド派な市田です。
今回は、みんな大好きVM Importについてのエントリになりますが、今回は「イメージによるインポート」についてご紹介したいと思います。
イメージのインポートとインスタンスのインポートの違い
VMインポートでよく混同されるのが、「イメージのインポート」と「インスタンスのインポート」です。それぞれインポートするものが異なり、利用するツールも異なります。
実際、ec2-api-toolsのことを公式ドキュメントでは「Amazon EC2 CLI」という表現になっており、「AWS CLI」と混同される要因の一つになっているのかもしれません。
いずれもコマンドラインから操作するので、よく混同される傾向があるようですが下記のような違いがあります。
特徴 | イメージのインポート | インスタンスのインポート |
---|---|---|
CLIサポート | AWS CLI | Amazon EC2 CLI (ec2-api-tools) |
インポートでサポートされる形式 | OVA、VHD、VMDK、raw | VHD、VMDK、raw |
複数ディスクのサポート | 可 | 不可 |
Windows BYOLサポート | 可 | 不可 |
作成されるもの | AMI (インスタンスは作成されない) |
EC2インスタンス (AMIは作成されない) |
今回の対象はイメージインポート
今回ご紹介するのは、イメージのインポートの方法についてです。
「インスタンスのインポート」については、下記のエントリで紹介させていただいています。
VM ImportでVMwareからAWS EC2へマイグレーションしてみた | Developers.IO
どちらがいいか
VMware環境からの単なる移行なら「インスタンスのインポート」が手っ取り早いと思いますが、ec2-api-toolsを使うための環境構築が少々手間になります。
イメージインポートの場合、AMIが作られる形になるため、AMIからインスタンスを作成する際に、セキュリティグループや、EBSサイズの指定などができます。
またAWS CLIは、MacやWindows、Linuxなどに比較的簡単にインストールできるので、個人的にはイメージインポートがお薦めかなと思います。
注意点
インポート可能なOSに制限などがあるので、事前に確認しておくようにしましょう。
手順の概要
- IAMユーザの作成と必要権限の付与
- インポートするVMの準備
- VMwareの環境からファイルエクスポート
- S3バケットの作成
- VM Import サービスロールの作成
- エクスポートしたファイルをS3へアップロード
- インポート
それでは、手順を見ていきたいと思います。
ちなみに、今回はCentOS6.8をインポートしてみます。
IAMユーザーに必要なアクセス許可の設定
専用のIAMユーザ(vmimportuser)を作成します。
ポリシーは下記の通りです。
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:ListAllMyBuckets" ], "Resource": "*" }, { "Effect": "Allow", "Action": [ "s3:CreateBucket", "s3:DeleteBucket", "s3:DeleteObject", "s3:GetBucketLocation", "s3:GetObject", "s3:ListBucket", "s3:PutObject" ], "Resource": ["arn:aws:s3:::mys3bucket","arn:aws:s3:::mys3bucket/*"] }, { "Effect": "Allow", "Action": [ "ec2:CancelConversionTask", "ec2:CancelExportTask", "ec2:CreateImage", "ec2:CreateInstanceExportTask", "ec2:CreateTags", "ec2:DeleteTags", "ec2:DescribeConversionTasks", "ec2:DescribeExportTasks", "ec2:DescribeInstanceAttribute", "ec2:DescribeInstanceStatus", "ec2:DescribeInstances", "ec2:DescribeTags", "ec2:ImportInstance", "ec2:ImportVolume", "ec2:StartInstances", "ec2:StopInstances", "ec2:TerminateInstances", "ec2:ImportImage", "ec2:ImportSnapshot", "ec2:DescribeImportImageTasks", "ec2:DescribeImportSnapshotTasks", "ec2:CancelImportTask" ], "Resource": "*" } ] }
作成したら、AWS CLIにこのユーザ情報を記載しておきます。
(私の場合、複数のIAMユーザがあるので、--profileオプションで切り替える為です。)
具体的な手順は下記をご確認ください。
AWS CLIへの設定方法
すでに複数のIAMユーザを使っている場合は、下記のようにユーザ毎の設定を追加します。
(想定している環境はMacです。)
$ aws configure --profile vmimportuser AWS Access Key ID [********************]: AWS Secret Access Key [********************]: Default region name [ap-northeast-1]: Default output format [None]:json
ステップ 1: インポートするVMの準備
AWSにイメージインポートするVMware仮想マシンに対して、事前に下記の作業を行っておきます。
- 仮想マシンにAWS CLIのインストール
- VMのウイルス対策ソフトウェアまたは侵入検出ソフトウェアを無効にする
- VMware VMからVMware Toolsをアンインストール
- あらゆる(仮想または物理)CD-ROMドライブを切断
- ネットワーク設定を、静的IPアドレスではなくDHCPに設定
- エクスポートする前にVMをシャットダウン
CentOS6の場合は、/etc/sysconfig/network-scripts/ifcfg-ethX
のファイルのBOOTPROTO
の設定をDHCPに変更します。
# 下記を変更 BOOTPROTO=dhcp
今回はCentOS6.8をインポートしますので、追加で以下の対応を行います。
- リモートアクセスの Secure Shell(SSH)を有効
- ホストのファイアウォール(Linux iptables など)でSSHへのアクセスが許可されていることを確認
- インポート後に、非ルートユーザーはパブリックキーベースのSSHを使用してインスタンスにアクセスするように設定されていることを確認
- Linux VM でブートローダーとして GRUB(GRUB レガシー)またはGRUB2が使用されていることを確認
- Linux VM で EXT2、EXT3、EXT4、Btrfs、JFS、XFS のいずれかのルートファイルシステムが使用されていることを確認
- CentOS6なので、EXT4になります。
参考:
ステップ 1: VM を準備する
ステップ 2: VMをその仮想化環境からエクスポート
VMwareからのエクスポートについてはご利用の環境に合わせて行ってください。 私の場合は、Macのローカル上にあるVMware Fusionの仮想マシンをエクスポートしました。
Macは標準ではVMマシンをエクスポートできないので、専用のツールである「VMware OVF Tool for Mac OSX」を別途インストールします。
下記ページからダウンロードしてインストールします。
インストールできたら早速ovftool
を使ってエクスポートを行います。今回はovf形式にしました。
$ /Applications/VMware\ OVF\ Tool/ovftool ¥ --acceptAllEulas /users/**********/Documents/Virtual\ ¥ Machines.localized/MYCentOS6.vmwarevm/MYCentOS6.vmx ~/mycentos68.ovf Opening VMX source: /users/**********/Documents/Virtual Machines.localized/MYCentOS6.vmwarevm/MYCentOS6.vmx Opening OVF target: /Users/**********/mycentos68.ovf Writing OVF package: /Users/**********/mycentos68.ovf Transfer Completed Completed successfully
完了すると「mycentos68.mf」「mycentos68.ovf」「mycentos68-disk1.vmdk」という3つのファイルが作成されています。
参考:
ステップ 2: VM をその仮想化環境からエクスポートする
ステップ 3: イメージとして VM をインポート
いよいよインポート作業に入ります。
作成したVMDKファイルを保存するS3バケットを作成
任意のS3バケットを作成します。既存のバケットでも構いません。
VM Import サービスロールの作成
公式ドキュメントにあるように、サービスロールの作成を行います。
VM Import では、Amazon S3 バケットからのディスクイメージのダウンロードなど、特定の操作の実行にロールが必要です。
以下のポリシーを定義したtrust-policy.json
という名前のファイルを作成します。
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "vmie.amazonaws.com" }, "Action": "sts:AssumeRole", "Condition": { "StringEquals":{ "sts:ExternalId": "vmimport" } } } ] }
create-role
コマンドを使用して、vmimport
という名前のロールを作成し、そのロールに VM Import/Export のアクセス権限を付与します。
今回は、vmimportuser
という名前のIAMユーザを利用しているので、--profile
でそのユーザ(vmimportuser)を指定しています。
aws iam --profile vmimportuser create-role --role-name vmimport --assume-role-policy-document file://trust-policy.json
次に下記のポリシーを定義したrole-policy.json
という名前のファイルを作成します。
disk-image-file-bucket
の箇所は、ステップ3で作成したバケット名を指定してください。
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:ListBucket", "s3:GetBucketLocation" ], "Resource": [ "arn:aws:s3:::disk-image-file-bucket" ] }, { "Effect": "Allow", "Action": [ "s3:GetObject" ], "Resource": [ "arn:aws:s3:::disk-image-file-bucket/*" ] }, { "Effect": "Allow", "Action":[ "ec2:ModifySnapshotAttribute", "ec2:CopySnapshot", "ec2:RegisterImage", "ec2:Describe*" ], "Resource": "*" } ] }
次にput-role-policy
コマンドを使用して、このポリシーを上記で作成したロールにアタッチします。
aws iam --profle vmimport put-role-policy --role-name vmimport --policy-name vmimport --policy-document file://role-policy.json
これらは、マネジメントコンソールから行っても構いません。
VMインポート
vmdkファイルのアップロード
作成したS3バケットに、エクスポートしたvmdkファイルをアップロードします。方法はなんでも構いません。今回は、AWS CLIでアップロード(コピー)しました。
(disk-image-file-bucketの箇所は作成したバケット名を指定してください。)
$ aws s3 cp --profile vmimportuser mycentos68-disk1.vmdk s3://disk-image-file-bucket/
VMのインポート
次に、インポートする各種パラメータを定義したcontainers.json
というファイルを作成します。
(disk-image-file-bucketの箇所は作成したバケット名を指定してください。)
単一ディスクの場合
[ { "Description": "My Original CentOS 6.8", "Format": "vmdk", "UserBucket": { "S3Bucket": "disk-image-file-bucket", "S3Key": "mycentos68-disk1.vmdk" } } ]
複数ディスクの場合
[ { "Description": "First disk", "Format": "vmdk", "UserBucket": { "S3Bucket": "my-import-bucket", "S3Key": "mycentos68-disk1.vmdk" } }, { "Description": "Second disk", "Format": "vmdk", "UserBucket": { "S3Bucket": "my-import-bucket", "S3Key": "mycentos68-disk1.vmdk" } } ]
import-image
コマンドを使用して、イメージインポートタスクを作成します。
$ aws ec2 import-image --profile vmimportuser --description "My CentOS6.8 VMDK" --disk-containers file://containers.json
実行すると下記のような表示が返ってきます。
{ "Status": "active", "Description": "My CentOS6.8 VMDK", "Progress": "2", "SnapshotDetails": [ { "UserBucket": { "S3Bucket": "mytest2016", "S3Key": "mycentos68-disk1.vmdk" }, "DiskImageSize": 0.0, "Format": "VMDK" } ], "StatusMessage": "pending", "ImportTaskId": "import-ami-fgzp52v0" }
このProgress
が100になれば完了です。
途中の進捗状況を確認する場合は、describe-import-image-tasks
コマンドで確認できます。このとき上記のImportTaskId
を指定します。
aws ec2 describe-import-image-tasks --import-task-ids import-ami-fgzp52v0
キャンセルする場合
aws ec2 cancel-import-task --import-task-id import-ami-fg4z7c9h
下記のように、Status
がcompleted
になれば完了です。
この状態で、AMIが使えるようになっています。
{ "ImportImageTasks": [ { "Status": "completed", "LicenseType": "BYOL", "Description": "My CentOS6.8 VMDK", "ImageId": "ami-********", "Platform": "Linux", "Architecture": "x86_64", "SnapshotDetails": [ { "DeviceName": "/dev/sda1", "Description": "My Original CentOS 6.8", "Format": "VMDK", "DiskImageSize": 1396196352.0, "SnapshotId": "snap-********", "UserBucket": { "S3Bucket": "mytest2016", "S3Key": "mycentos68-disk1.vmdk" } } ], "ImportTaskId": "import-ami-fgzp52v0" } ] }
後は、EC2インスタンスを作成したり、AMIを別のリージョンにコピーして利用したりと、普通に使えます。
参考:
ステップ 3: イメージとして VM をインポートする
最後に
AWS CLIだけで利用できるのでインスタンスのインポートに比べて、随分と楽にVM Importできました。 利用可能なOSの制限などがありますが、手軽にインポートできるのは魅力的だと思います。
以上になります。